#include <QtTest>

#include "../tests_common.h"

#include "bitwin/roles.h"
#include "bitwin/bit_range.h"
#include "bitwin/rows.h"


using namespace BitWin;


class TestFieldRow: public QObject
{
    Q_OBJECT

private slots:

    void testMisc_data();
    void testMisc();

    void testData_data();
    void testData();
};


void TestFieldRow::testMisc_data()
{
    QTest::addColumn<QString>("title");
    QTest::addColumn<BitRange>("range");
    QTest::addColumn<int>("word_no");
    
    QTest::newRow("Case 1")
        << QString("field #1") << BitRange(3, 6) << 1
    ;
    QTest::newRow("Case 2")
        << QString("field #2") << BitRange(3, 6) << 4
    ;
    QTest::newRow("Case 3")
        << QString("") << BitRange(1, 6) << 2
    ;
    QTest::newRow("Case 4")
        << QString() << BitRange(1, 6) << 0
    ;
    QTest::newRow("Null range")
        << QString("field #5") << BitRange() << 5
    ;
    QTest::newRow("Reverse range")
        << QString("field #6") << BitRange(10, 1) << 5
    ;
}

void TestFieldRow::testMisc()
{
    QFETCH(QString, title);
    QFETCH(BitRange, range);
    QFETCH(int, word_no);
    
    FieldRow row(title, range, word_no);
    QCOMPARE(row.title(), title);
    QCOMPARE(row.wordNo(), word_no);
}

void TestFieldRow::testData_data()
{
    QTest::addColumn<BitRange>("field_range");
    QTest::addColumn<QString>("indata");
    QTest::addColumn<BitRange>("requested_range");
    QTest::addColumn<QString>("outdata_expected");
    
    QTest::newRow("field [3, 6), range [0, 8)")
        << BitRange(3, 6) << QString("abcdefgh")
        << BitRange(0, 8) << QString("   def  ")
    ;
    QTest::newRow("field [3, 6), range [3, 6)")
        << BitRange(3, 6) << QString("abcdefgh")
        << BitRange(3, 6) << QString(   "def")
    ;
    QTest::newRow("field [1, 6), range [3, 7)")
        << BitRange(1, 6) << QString("abcdefgh")
        << BitRange(3, 7) << QString(   "def ")
    ;
    QTest::newRow("field [3, 6), range [1, 5)")
        << BitRange(3, 6) << QString("abcdefgh")
        << BitRange(1, 5) << QString( "  de")
    ;
    QTest::newRow("field [0, 8), range [3, 6)")
        << BitRange(0, 8) << QString("abcdefgh")
        << BitRange(3, 6) << QString(   "def")
    ;
    QTest::newRow("Null range")
        << BitRange(0, 8) << QString("abcdefgh")
        << BitRange() << QString()
    ;
    QTest::newRow("Requested range exceeds indata")
        << BitRange(1, 6) << QString("abcdefgh")
        << BitRange(1, 10) << QString("bcdef    ")
    ;
    QTest::newRow("Field range exceeds indata")
        << BitRange(1, 6) << QString("abc")
        << BitRange(0, 3) << QString(" bc")
    ;
    QTest::newRow("Both ranges exceed indata")
        << BitRange(1, 6) << QString("abc")
        << BitRange(0, 6) << QString(" bc   ")
    ;
}

void TestFieldRow::testData()
{
    QString title("Field row");
    QFETCH(BitRange, field_range);
    int word_no = 0;
    
    FieldRow row(title, field_range, word_no);
    
    QFETCH(QString, indata);
    QFETCH(BitRange, requested_range);
    
    QVERIFY(
        !row
            .data(Qt::DisplayRole, requested_range, STRING_BITWISE(indata))
            .isValid()
    );
    QVERIFY(
        !row
            .data(BitwiseDataRole + 1, requested_range, STRING_BITWISE(indata))
            .isValid()
    );
    
    QVariant data(
        row
            .data(BitwiseDataRole, requested_range, STRING_BITWISE(indata))
    );
    QVERIFY(data.isValid());
    QVERIFY(data.canConvert<QString>());
    QString outdata(data.value<QString>());
    
    QFETCH(QString, outdata_expected);
    QCOMPARE(outdata, outdata_expected);
}


QTEST_MAIN(TestFieldRow)


#include "main.moc"
